package com.data_structure_test.hashtable;

import java.util.HashSet;
import java.util.Random;

public class SeplinkSet<T> {

    private double load_factor = 10f;

    private Node<T>[] array;

    private int currentSize;

    private int tableSize;

    private HashFunction<T> hashFunction;

    private class Node<T>{

        T value;
        Node<T> next;

        Node(T value,Node<T> next){
            this.value = value;
            this.next = next;
        }
    }

    private class HashFunction<T>{
        int hash(T value){
            return value.hashCode()%tableSize;
        }

    }


    public SeplinkSet(int initSize){
       resize(initSize);
    }

    private void resize(int initSize) {
        array = new Node[initSize];
        tableSize = initSize;
        hashFunction = new HashFunction<>();
        currentSize = initSize;
    }

    public SeplinkSet(){
        this(1000);
    }

    public void add(T value){
        int index;
        Node<T> tmp;
        if((tmp = array[(index = hash(value))]) == null){
            array[index] = new Node<>(value,null);
        }else{
            while (tmp.next != null){
                tmp = tmp.next;
            }
            tmp.next = new Node<>(value,null);
        }
        if(currentSize >= tableSize * load_factor){
            resizeAndCopy(tableSize * 2);
        }

    }

    private void resizeAndCopy(int tableSize) {

        Node<T>[] tmp = array;
        resize(tableSize);
        System.arraycopy(tmp,0,array,0,tmp.length);
    }


    public boolean contains(T value){
        int index;
        Node<T> tmp;
        if((tmp = array[(index = hash(value))]) != null){
            while (tmp.next != null){
                if(tmp.value == value){
                    return true;
                }
                tmp = tmp.next;
            }
        }
        return false;
    }


    private int hash(T value){
       return hashFunction.hash(value);
    }


    public static void main(String[] args){
        int count = 1000000;
        int number = 100000;

        Random rand = new Random();
        SeplinkSet<Integer> set = new SeplinkSet<>();
        HashSet<Integer> hashSet = new HashSet<>();

        long start = System.currentTimeMillis();

        for(int i = 1;i < count;i ++ ){
            set.add(rand.nextInt(number));
            //hashSet.add(rand.nextInt(number));
        }

        long end = System.currentTimeMillis();

        System.out.println(end - start);


    }




}
